package com.xyoto.community.recover;

import com.xyoto.community.cache.CacheInstruction;
import com.xyoto.community.config.TopicUserHotTableConfig;
import com.xyoto.community.constant.DeleteStatus;
import com.xyoto.community.constant.LoveStatus;
import com.xyoto.community.constant.PersonalStatus;
import com.xyoto.community.constant.TopicUserHotType;
import com.xyoto.community.entity.comment.DynamicComment;
import com.xyoto.community.entity.comment.DynamicCommentReply;
import com.xyoto.community.entity.love.DynamicCommentLove;
import com.xyoto.community.entity.love.DynamicCommentReplyLove;
import com.xyoto.community.entity.love.DynamicLove;
import com.xyoto.community.entity.main.Dynamic;
import com.xyoto.community.entity.main.DynamicForward;
import com.xyoto.community.entity.main.OtherTopicUserHot;
import com.xyoto.community.entity.main.TopicUserHot;
import com.xyoto.community.mapper.comment.DynamicCommentMapper;
import com.xyoto.community.mapper.comment.DynamicCommentReplyMapper;
import com.xyoto.community.mapper.love.DynamicCommentLoveMapper;
import com.xyoto.community.mapper.love.DynamicCommentReplyLoveMapper;
import com.xyoto.community.mapper.love.DynamicLoveMapper;
import com.xyoto.community.mapper.main.DynamicForwardMapper;
import com.xyoto.community.mapper.main.DynamicMapper;
import com.xyoto.community.mapper.main.OtherTopicUserHotMapper;
import com.xyoto.community.mapper.main.TopicUserHotMapper;
import com.xyoto.community.pojo.Type2TopicUserHotTableInfo;
import com.xyoto.community.utils.RedisCommonUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * 新版恢复用户热度的热度数据恢复类，可根据最新配置的规则重新计算用户总榜、话题下的用户榜单
 * Author: 廖振辉
 * Date: 2022/2/28
 * Description:
 */
//@SpringBootTest(classes = {CommunityApplication.class})
public class UserHotRecoverNew {

    @Autowired
    private TopicUserHotTableConfig topicUserHotTableConfig;

    String startTime = "2022-02-28 07:00:00";

    @Autowired
    private DynamicForwardMapper dynamicForwardMapper;

    @Autowired
    private RedisCommonUtils redisCommonUtils;

    @Autowired
    private DynamicCommentReplyLoveMapper dynamicCommentReplyLoveMapper;

    @Autowired
    private DynamicCommentReplyMapper dynamicCommentReplyMapper;

    @Autowired
    private DynamicMapper dynamicMapper;

    @Autowired
    private DynamicCommentLoveMapper dynamicCommentLoveMapper;

    @Autowired
    private DynamicCommentMapper dynamicCommentMapper;

    @Autowired
    private DynamicLoveMapper dynamicLoveMapper;

    @Autowired
    private OtherTopicUserHotMapper otherTopicUserHotMapper;

    @Autowired
    private TopicUserHotMapper topicUserHotMapper;

    // 测试活跃度规则是否正确配置
//    @Test
    public void test() {
        Map<Integer, Double> operateType2ScoreMap = topicUserHotTableConfig.getOperateType2ScoreMap();
        operateType2ScoreMap.forEach((k, v) -> {
            System.out.println(k + " = " + v);
        });
    }

    // planA,从各个表扫描数据重新计算用户总榜热度
//    @Test
    public void refreshA(){
        redisCommonUtils.del(CacheInstruction.USER_RANK);
        dynamicForwardHot();
        publishDynamicHot();
        dynamicLoveHot();
        dynamicCommentLoveHot();
        dynamicCommentReplyLoveHot();
        comment();
        replyHot();
    }

    // planB,从用户热度表扫描数据重新计算用户总榜热度
//    @Test
    public void refreshB(){
        redisCommonUtils.del(CacheInstruction.USER_RANK);
        reCalcHot();
    }

    // 刷新用户的动态转发热度
//    @Test
    public void dynamicForwardHot() {
        List<DynamicForward> dynamicForwardList = dynamicForwardMapper.selectAllStartFrom(startTime);
        Double score = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.FORWARD);
        for (DynamicForward dynamicForward : dynamicForwardList) {
            Integer userId = dynamicForward.getUserId();
            System.out.println(dynamicForward);
            redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,score);
        }
    }

    // 刷新动态产生的用户热度
//    @Test
    public void publishDynamicHot() {
        List<Dynamic> dynamicList = dynamicMapper.getAllStartFrom(startTime, DeleteStatus.NO, PersonalStatus.VISIBLE_TO_ALL);
        Double score = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.PUBLISH_DYNAMIC);
        for (Dynamic dynamic : dynamicList) {
            Integer userId = dynamic.getUserId();
            System.out.println(dynamic);
            redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,score);
        }
    }

    // 重新计算动态点赞产生的用户热度
//    @Test
    public void dynamicLoveHot() {
        List<DynamicLove> dynamicLoveList = dynamicLoveMapper.getAllStartFrom(startTime, LoveStatus.LOVE);
        Double loveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.LOVE);
        Double beLoveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.DYNAMIC_BE_LOVE);
        for (DynamicLove dynamicLove : dynamicLoveList) {
            Integer userId = dynamicLove.getUserId();
            Dynamic dynamic = dynamicMapper.getDynamicById(dynamicLove.getDynamicId());

            // 如果动态还存在
            if (dynamic != null) {
                // 给主动点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,loveScore);

                // 给被点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,dynamic.getUserId(),beLoveScore);
                System.out.println(dynamicLove);
            }
        }
    }

    // 重新计算动态评论点赞产生的用户热度
//    @Test
    public void dynamicCommentLoveHot() {
        List<DynamicCommentLove> dynamicCommentLoveList = dynamicCommentLoveMapper.getAllStartFrom(startTime, LoveStatus.LOVE);
        Double loveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.LOVE);
        Double beLoveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.DYNAMIC_BE_LOVE);
        for (DynamicCommentLove dynamicCommentLove : dynamicCommentLoveList) {
            Integer userId = dynamicCommentLove.getUserId();
            DynamicComment dynamicComment = dynamicCommentMapper.selectOneByDynamicCommentId(dynamicCommentLove.getDynamicCommentId());
            // 如果动态还存在
            if (dynamicComment != null) {
                // 给主动点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,loveScore);

                // 给被点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,dynamicComment.getUserId(),beLoveScore);
            }
        }
    }

    // 重新计算动态评论回复点赞产生的用户热度
//    @Test
    public void dynamicCommentReplyLoveHot() {
        List<DynamicCommentReplyLove> dynamicCommentLoveList = dynamicCommentReplyLoveMapper.getAllStartFrom(startTime, LoveStatus.LOVE);
        Double loveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.LOVE);
        Double beLoveScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.DYNAMIC_BE_LOVE);
        for (DynamicCommentReplyLove dynamicCommentReplyLove : dynamicCommentLoveList) {
            Integer userId = dynamicCommentReplyLove.getUserId();
            Integer replyId = dynamicCommentReplyLove.getDynamicCommentReplyId();
            DynamicCommentReply reply = dynamicCommentReplyMapper.selectOneByDynamicCommentReplyId(replyId);

            // 如果动态还存在
            if (reply != null) {
                // 给主动点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,loveScore);

                // 给被点赞的加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,reply.getUserId(),beLoveScore);
            }
        }
    }


    // 刷新评论产生的用户热度
//    @Test
    public void comment() {
        List<DynamicComment> dynamicCommentList = dynamicCommentMapper.getAllStartFrom(startTime, DeleteStatus.NO);
        Double commentScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.COMMENT);
        Double beCommentScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.BE_COMMENT);

        for (DynamicComment dynamicComment : dynamicCommentList) {
            Integer userId = dynamicComment.getUserId();
            Dynamic dynamic = dynamicMapper.getDynamicById(dynamicComment.getDynamicId());
            if (dynamic != null) {
                // 给评论人加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,commentScore);

                // 给被评论的人加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,dynamic.getUserId(),beCommentScore);
                System.out.println(dynamicComment);
            }
        }
    }

    // 刷新回复产生的用户热度
//    @Test
    public void replyHot(){
        List<DynamicCommentReply> dynamicCommentReplyList = dynamicCommentReplyMapper.getAllStartFrom(startTime,DeleteStatus.NO);
        Double replyScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.REPLY);
        Double beReplyScore = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.BE_REPLY);

        for (DynamicCommentReply dynamicCommentReply : dynamicCommentReplyList) {
            Integer userId = dynamicCommentReply.getUserId();
            Integer replyId = dynamicCommentReply.getTargetDynamicCommentReplyId();
            if (replyId == null){
                // 回复评论

//                // 给主动回复的人加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,replyScore);

                // 给被回复的人加分
                DynamicCommentReply reply = dynamicCommentReplyMapper.selectOneByDynamicCommentReplyId(replyId);
                if (reply != null){
                    redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,reply.getUserId(),beReplyScore);
                }

            }else {
                // 回复回复

                // 给主动回复的人加分
                redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,replyScore);

                // 给被回复的人加分
                DynamicComment dynamicComment = dynamicCommentMapper.selectOneByDynamicCommentId(dynamicCommentReply.getDynamicCommentId());
                if (dynamicComment != null){
                    redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,dynamicComment.getUserId(),beReplyScore);
                }
            }
        }
    }

    // 根据活跃度总表，重新计算用户的热度，但无法去除因为删除动态、取消点赞而增加的活跃度
//    @Test
    void reCalcHot() {
        List<OtherTopicUserHot> scoreList = otherTopicUserHotMapper.getAllStartFrom(startTime);
        redisCommonUtils.del(CacheInstruction.USER_RANK);
        for (OtherTopicUserHot otherTopicUserHot : scoreList) {
            Double score = topicUserHotTableConfig.getScoreByOperateType(otherTopicUserHot.getType());
            Integer userId = otherTopicUserHot.getUserId();
            redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK, userId, score);
        }
    }

    // 更新用户删除动态后的用户热度
//    @Test
    public void deleteDynamicHot(){
        // 删掉动态了的动态集合
        List<Dynamic> dynamicList = dynamicMapper.getAllStartFrom(startTime, DeleteStatus.YES, PersonalStatus.VISIBLE_TO_ALL);
        // 设为私密但是没删的
        dynamicList.addAll(dynamicMapper.getAllStartFrom(startTime,DeleteStatus.NO,PersonalStatus.VISIBLE_TO_PERSONAL));
        // 设为私密再删的
        dynamicList.addAll(dynamicMapper.getAllStartFrom(startTime,DeleteStatus.YES,PersonalStatus.VISIBLE_TO_PERSONAL));
        Double score = topicUserHotTableConfig.getScoreByOperateType(TopicUserHotType.DELETE_DYNAMIC);

        for (Dynamic dynamic : dynamicList) {
            Integer userId = dynamic.getUserId();
            System.out.println(userId);
            redisCommonUtils.incrementScoreForZSet(CacheInstruction.USER_RANK,userId,score);
        }
        System.out.println("dynamicList.size() = " + dynamicList.size());
    }

    // 根据话题下的活跃度表，从指定时间开始，重新计算各个话题下的用户榜单
//    @Test
    public void reCalcUserHotInTopic(){
        for (int i = 1; i <= 11; i++) {
            Type2TopicUserHotTableInfo tableInfo = topicUserHotTableConfig.getTopicUserHotInfoByTopicId(i);
            if (tableInfo == null){
                continue;
            }
            String tableName = tableInfo.getTableName();
            List<TopicUserHot> topicUserHotList = topicUserHotMapper.selectAllStartFrom(tableName,startTime);
            redisCommonUtils.del(tableName);
            for (TopicUserHot topicUserHot : topicUserHotList) {
                Integer userId = topicUserHot.getUserId();
                Integer type = topicUserHot.getType();
                Double score = topicUserHotTableConfig.getScoreByOperateType(type);
                redisCommonUtils.incrementScoreForZSet(tableName,userId,score);
            }
        }
    }

}
